package technion.gc.api.implementation;

import java.util.HashSet;

import technion.gc.api.implementation.interfaces.IGraphCrawler;
import technion.gc.api.interfaces.*;

/** Main Graph Crawler class.
 */
public class GraphCrawler implements IGraphCrawler {
	/** The Traversal Strategy to use.
	 */
	private ITraversalStrategy traversalStrategy;
	
	/** The Graph Node Action to use.
	 */
	private IGraphNodeAction graphNodeAction;
	
	/** C'tor to make new Graph Crawler.
	*
	* @param _traversalStrategy	Traversal Strategy
	* @param _graphNodeAction	Graph Node Action
	*/
	public GraphCrawler(ITraversalStrategy _traversalStrategy, 
			IGraphNodeAction _graphNodeAction) {
		traversalStrategy = _traversalStrategy;
		graphNodeAction = _graphNodeAction;
	}
	
	/** Traverses the graph parameter using the c'tor 
	*   supplied Traversal Strategy and Graph Node Action.
	*
	* @param graph	The graph to traverse.
	*/
	@Override
	public void traverseGraph(IGraph graph) {
		traversalStrategy.setGraph(graph);
		HashSet<AbstractGraphNode> visited = new HashSet<AbstractGraphNode>();
		while (traversalStrategy.hasNextGraphNode()) {
			AbstractGraphNode next = traversalStrategy.getNextGraphNode();
			if (!visited.contains(next)) {
				graphNodeAction.execute(next);
				visited.add(next);
				traversalStrategy.encountered(next);
			}
			else {
				traversalStrategy.encounteredAgain(next);
			}
		}
		traversalStrategy.cleanup();
	}
}
